import { get } from '@/axios/http'
import OSS from 'ali-oss'
import { AliOssConfig, ServerConfig } from './config'
import { v4 as uuid } from 'uuid'

async function OssClient() {
  const retoken = await getSTSToken()
  if (!retoken.isSuccess) {
    return null
  }
  //后端提供数据
  return new OSS({
    region: AliOssConfig.region, //oss-cn-beijing-internal.aliyuncs.com
    accessKeyId: retoken.tokenInfo?.accessKeyId,
    accessKeySecret: retoken.tokenInfo?.accessKeySecret,
    stsToken: retoken.tokenInfo?.securityToken,
    bucket: AliOssConfig.bucket,
    refreshSTSToken: async () => {
      const re = await getSTSToken()
      if (re.isSuccess) {
        return re.tokenInfo
      } else {
        return {
          accessKeyId: '',
          accessKeySecret: '',
          expiration: '',
          securityToken: ''
        }
      }
    },
    // 刷新临时访问凭证的时间间隔，单位为毫秒。
    refreshSTSTokenInterval: AliOssConfig.refreshTokenTime * 60 * 1000
  })
}
const getSTSToken = async (): Promise<{
  isSuccess: Boolean
  msg: String
  tokenInfo?: {
    accessKeyId: String
    accessKeySecret: String
    expiration: String
    securityToken: String
  }
}> => {
  const re = await get('/project/common/oss/getSts').catch((err) => {
    return err.response || err
  })
  if (!re)
    return {
      isSuccess: false,
      msg: '操作失败：服务端操作失败'
    }
  if (!re.data)
    return {
      isSuccess: false,
      msg: '操作失败：服务端未返回结果'
    }
  return {
    isSuccess: re.data.success,
    msg: re.data.message,
    tokenInfo: re.data.data.credentials
  }
}
class AliOss {
  private ossClient: any
  private REG = /.*(\.[^.]+)$/
  upload = async (
    file,
    onUploading?: (percent: number) => void
  ): Promise<{
    isSuccess: boolean
    msg: string
    path: string
    remotePath: string
  }> => {
    const suffixName = `${AliOssConfig.Path}${uuid()}${file.name.replace(this.REG, '$1')}`
    if (!this.ossClient) this.ossClient = await OssClient()
    const res = await this.ossClient
      ?.multipartUpload(suffixName, file, {
        'Cache-Control': 'no-cache',
        // 设置并发上传的分片数量。
        parallel: 4,
        // 设置分片大小。默认值为1 MB，最小值为100 KB。
        partSize: 1024 * 1024,
        progress: (p, cpt, res) => {
          let per = p as number
          if (onUploading) onUploading(parseFloat((per * 100).toFixed(2)))
        }
      })
      .catch((err) => err.response || err)
    if (res.res && res.res.status === 200) {
      const url = `/${res.name}`
      return {
        isSuccess: true,
        msg: '',
        path: url,
        remotePath: `${ServerConfig.REMOTE_FILE_BASE}/${url}`
      }
    } else {
      return {
        isSuccess: false,
        msg: '上传失败',
        path: '',
        remotePath: ''
      }
    }
  }
  remove = async (url) => {
    if (!url) return
    if (!this.ossClient) this.ossClient = await OssClient()
    const re = await this.ossClient.delete(url)
    console.log('res', re.res)
  }
}
export const Oss = new AliOss()
